#!/usr/bin/env python
# -*- coding: utf-8 -*-


"""
    Part of Seagull - The Pyhon Pages engine
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    compile:
      The compile script which calls the compiler for every
      single Python Page and prints succes/failure.
"""


help = \
"""
Python Pages compiler

Usage: compile.py [ -o | --only-changed] [-h | --help]

-o            | --only-changed      (Compile only changed files)
-h            | --help              (Shows this help)
"""
__author__ = 'Jonathan Slenders <jonathan at slenders dot be>'
__license__ = 'GNU LGPL'
__all__ = ('PageCompiler', )


import os
import sys
import codecs
import time
import xml.dom.minidom
import posixpath
import platform
import getopt

try:
	import configuration
	configuration.SystemConfig()

except Exception, e:
	print e
	sys.exit(1)

import page_providers
from compiler.compiler import Compiler
from compiler.compile_exceptions import CompileException

class PageCompiler(object):
	"""
	Compiles ALL the pages
	"""
	def __init__(self):
		self.__compile_errors = 0
		self._config = configuration.SystemConfig()

	def compile_all(self, compile_only_changed_files=False):
		""" Compile all pages """
		# For each page provider
		for provider in self._config.page_providers:
			self._call_walk(provider, compile_only_changed_files)
		
		# Show result
		if self.__compile_errors == 0:
			self.__print_title('==> Compilation succesful')
		else:
			self.__print_error('==> Compilation failed: %s errors' % self.__compile_errors)

	def compile_page(self, pythonpage):
		""" Compile python page, this could raise Compiler.CompileException """
		assert isinstance(pythonpage, page_providers.PythonPage)

		source = pythonpage.get_source()
		compiler = Compiler(source, pythonpage.path, debug=self._config.debug)
		pythonpage.save_compiled_page(compiler.get_compiled_script())
		pythonpage.save_meta_data(compiler.get_reflexion_info())

		# TEMP: update source file to new syntax
		### import compiler.lexer
		### import compiler.parser
		### import compiler.writeback
		### p = compiler.lexer.Lexer(source).get_result()
		### p = compiler.parser.Parser(p).get_result()
		### new_source = compiler.writeback.WriteBack(p).get_result()
		### pythonpage.save_source(new_source)

	def _call_walk(self, provider, only_changed_files):
		for page in provider.walk():
			# Walk through the python pages of this page provider
			if isinstance(page, page_providers.PythonPage):
				if not only_changed_files or page.has_been_changed():
					self.__print_title('Compiling: %s' % page.path)

					# Delete eventual previous compiled data
					page.delete_previous_compile_result()

					try:
						# Compile
						self.compile_page(page)

					except CompileException, e:
						# Remember error
						self.__print_error(str(e))
						self.__compile_errors += 1

			# Call directories recursively
			elif isinstance(page, page_providers.Directory):
				self._call_walk(page, only_changed_files)

	def __print_title(self, str):
		print ('\033[34m %s \033[0m' % str)
	def __print_error(self, str):
		print ('\033[31m %s \033[0m' % str)



################################################################
# Main
################################################################

if __name__ == '__main__':
	# Parse comand line options
	opts, args = getopt.gnu_getopt(sys.argv[1:], 'hoda', ['help', 'only-changed' ])

	settings = {
		'help': False,
		'only-changed': False,
	}

	for option in opts:
		if option[0] in ('--help', '-h'):
			settings['help'] = True

		elif option[0] in ('--only-changed', '-o'):
			settings['only-changed'] = True

	# Start compiler
	start = time.clock()
	PageCompiler().compile_all(compile_only_changed_files=settings['only-changed'])

	dur = time.clock() - start
	print 'Compile time: %s' % dur


